﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using OpenChart.Entities;
using System.Data;

using OpenChart.PublicUnits;

namespace OpenChart.DrawChart
{
    /// <summary>
    /// 折线图
    /// </summary>
    class DrawingLineChart : AbsDrawingChart
    {
        /// <summary>
        /// 绘制数据
        /// </summary>
        protected override void DrawData()
        {
            if (this.ChartArea.Series != null)
            {
                this.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                foreach (var item in this.ChartArea.Series)
                {
                    this.DrawSeries(item);
                }
                this.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
            }
        }

        /// <summary>
        /// 绘制Series
        /// </summary>
        /// <param name="item">Series</param>
        protected virtual void DrawSeries(Series item)
        {
            Brush brush = new SolidBrush(item.Color);
            Pen pen = new Pen(brush, item.Width);
            List<PointF> points = new List<PointF>();
            for (int i = 0; i < this.ChartArea.Data.Rows.Count; i++)
            {
                double xValue = ChartHelper.GetDoubleValue(this.ChartArea.Data.Rows[i][this.ChartArea.XValueMember], this.ChartArea.AxisX.IntervalType);
                if (xValue < _minXValue || xValue > _maxXValue)
                {
                    continue;
                }
                double yValue = ChartHelper.GetDoubleValue(this.ChartArea.Data.Rows[i][item.YValueMember], this.ChartArea.AxisY1.IntervalType);
                if (yValue < _minYValue || yValue > _maxYValue)
                {
                    continue;
                }
                points.Add(this.GetPoint(xValue, yValue));
            }
            if (points.Count > 1)
            {
                this.Graphics.DrawLines(pen, points.ToArray());
            }
        }

        /// <summary>
        /// 根据数据计算坐标点位置
        /// </summary>
        /// <param name="xValue">X轴对应的数据值</param>
        /// <param name="yValue">Y轴对应的数据值</param>
        /// <returns>坐标点</returns>
        protected PointF GetPoint(double xValue,double yValue)
        {
            float xValuePerPixel = (float)(_maxXValue - _minXValue) / (CanvasWidth - CON_RIGTH_RANGE - CON_LEFT_RANGE);
            float yValuePerPixel = (float)(_maxYValue - _minYValue) / (this.CanvasHeight - CON_DOWN_RANGE - CON_UP_RANGE);

            PointF point = new PointF();
            point.X = CON_LEFT_RANGE + (float)((xValue - _minXValue) / xValuePerPixel);
            point.Y = this.CanvasHeight - CON_DOWN_RANGE - (float)(yValue - _minYValue) / yValuePerPixel;

            return point;
        }
    }
}
